package com.soup.lab.basic.reflection;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.stream.Stream;

public class MethodTestCase {

    @Test
    public void test() throws ReflectiveOperationException {
        Field f1 = A.class.getDeclaredField("name");
        Field f2 = A.class.getDeclaredField("name");
        Assertions.assertFalse(f1 == f2);
        Method m1 = A.class.getDeclaredMethod("getName");
        Method m2 = A.class.getDeclaredMethod("getName");
        Assertions.assertFalse(m1 == m2);
    }

    @Test
    public void test2() throws ReflectiveOperationException {
        Field f1 = A.class.getDeclaredField("name");
        f1.setAccessible(true);
        Assertions.assertTrue(f1.isAccessible());
        Field f2 = A.class.getDeclaredField("name");
        Assertions.assertFalse(f2.isAccessible());
    }

    @Test
    public void test3() throws IntrospectionException {
        BeanInfo b1 = Introspector.getBeanInfo(A.class);
        BeanInfo b2 = Introspector.getBeanInfo(A.class);
        Assertions.assertTrue(b1 == b2);
        PropertyDescriptor[] pd = b1.getPropertyDescriptors();
        Stream.of(pd).map(PropertyDescriptor::getReadMethod)
                .filter(Objects::nonNull)
                .forEach(m -> m.setAccessible(true));
        PropertyDescriptor[] pd2 = b2.getPropertyDescriptors();
        Stream.of(pd2).map(PropertyDescriptor::getReadMethod)
                .filter(Objects::nonNull)
                .forEach(m -> System.out.println(m.isAccessible()));
    }

    static class A {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }


}
